<template>
  <el-upload drag v-model:file-list="fileList" :before-upload="handleBeforeUpload" :http-request="handleUpload" :on-exceed="handleExceed" :on-success="uploadSuccess" :on-error="uploadError" :accept="accept" :limit="limit" :style="updateStyle" :multiple="multiple" :show-file-list="showFileList">
    <el-icon class="el-icon--upload">
      <upload-filled />
    </el-icon>
    <div v-loading="loading" element-loading-text="文件上传中..." class="el-upload__text">将文件拖到此处，<br />或<em>点击上传</em></div>
    <template #tip>
      <div class="el-upload__tip text-red">请上传{{ props.fileType }}标准格式文件</div>
    </template>
  </el-upload>
</template>

<script setup lang="ts">
import { ref, watch } from "vue";
import { ElNotification, UploadRawFile, UploadRequestOptions, UploadUserFile } from "element-plus";
import baseService from "@/service/baseService";
import app from "@/constants/app";
import { getToken } from "@/utils/cache";

const uploadURL = `/sys/oss/upload?token=${getToken()}`;

const loading = ref(false);

interface UploadFileProps {
  ossPath: string; // 文件地址 ==> 必传
  ossName: string; // 文件名称 ==> 必传
  showFileList?: boolean; //
  multiple?: boolean; //
  limit?: number; //
  accept?: string; //
  fileType?: string; //
  fileSize?: number; // 单个文件大小限制 ==> 非必传（默认为 500M）
  updateStyle?: { [key: string]: any }; // 上传组件样式 ==> 非必传
}

// 接受父组件参数
const props = withDefaults(defineProps<UploadFileProps>(), {
  ossPath: "",
  ossName: "",
  showFileList: true,
  multiple: true,
  limit: 1,
  accept: "*",
  fileType: "",
  fileSize: 500,
  updateStyle: () => ({ width: "50%" })
});

const fileList = ref([] as UploadUserFile[]);

watch(
  () => props.ossPath,
  () => {
    if (props.ossPath) {
      fileList.value[0] = {
        url: props.ossPath,
        name: props.ossPath.split("/")[2]
      };
    }
  }
);

interface UploadEmits {
  (e: "update:ossPath", value: string): void;

  (e: "update:ossName", value: string): void;
}

const emit = defineEmits<UploadEmits>();

/**
 * 自定义文件上传
 *
 * @param params
 */
async function handleUpload(options: UploadRequestOptions): Promise<any> {
  const formData = new FormData();
  formData.append("file", options.file);
  loading.value = true;
  baseService
    .post(uploadURL, formData)
    .then((res) => {
      if (res.code === 0 && res.data.src) {
        console.log(res.data.src,"res.data.src");
        emit("update:ossPath", res.data.src);
        emit("update:ossName", options.file.name);
        ElNotification({
          title: "温馨提示",
          message: "文件上传成功！",
          type: "success"
        });
      }
    })
    .finally(() => {
      loading.value = false;
    });
}

/**
 * 限制用户上传文件的格式和大小
 */
function handleBeforeUpload(file: UploadRawFile) {
  const imgSize = file.size / 1024 / 1024 < props.fileSize;
  const imgType = props.accept!.split("/") || []; //["image/jpg", "image/jpeg", "image/png"];
  console.log(imgType, "props", file.type);
  if (!imgType.includes(file.type.split("/")[0])) {
    ElNotification({
      title: "温馨提示",
      message: "上传文件格式错误！",
      type: "warning"
    });
    return;
  }
  if (!imgSize) {
    ElNotification({
      title: "温馨提示",
      message: `上传文件大小不能超过 ${props.fileSize}MB！`,
      type: "warning"
    });
    return;
  }
}

// 文件数超出提示
const handleExceed = (): void => {
  ElNotification({
    title: "温馨提示",
    message: `最多只能上传${props.limit}个文件！`,
    type: "warning"
  });
};

// 图片上传成功提示
const uploadSuccess = () => {
  // ElNotification({
  //   title: "温馨提示",
  //   message: "文件上传成功！",
  //   type: "success"
  // });
};

// 图片上传错误提示
const uploadError = () => {
  ElNotification({
    title: "温馨提示",
    message: "文件上传失败，请您重新上传！",
    type: "error"
  });
};
</script>
